package org.sql.commands.mysql.command;

// *************************************************************************/
// Charada Soft
// Area de Desarrollo de Sistemas de Información
// *************************************************************************/
// Proyecto : java connector sql 
// Archivo : Insert.java
// Descripcion : Clase Insert
// *************************************************************************/
// Version : 2.10.4
// Fecha de Creación: 30 de Junio de 2014
// Author : Daniel Andres Castillo Pedroza
// *************************************************************************/

import java.util.ArrayList;
import org.sql.commands.exception.DMLException;

public class Insert extends DML {

    // Atributos estáticos de la clase Insert
    public static final boolean STANDARD = false;
    public static final boolean SPECIFIC = true;

    // Atributos de la clase Insert
    private String table;
    private ArrayList<String> columns;
    private int numValues;
    private boolean mode;

    // Constructor de la clase Insert
    public Insert() {
        columns = new ArrayList<>(); mode = STANDARD;
    }

    // Metodos de la clase Insert
    /**
     * Este método nos permite establecer el Nombre de la Tabla del Comando a
     * ejecutar. Donde la tabla se establece con un objeto <code>String</code>.
     *
     * @param table Nombre de Tabla del Comando
     */
    public void setTable(String table) {
        this.table = table;
    }

    /**
     * Este método nos permite establecer el Nombre de las Columnas del Comando
     * a ejecutar. Donde las columnas se establecen con un objeto
     * <code>ArrayList</code>. Ademas, se determina que el modo de Insercción es
     * Específico.
     *
     * @param columns Nombre de las Columnas del Comando
     * @see #SPECIFIC
     */
    public void setColumns(ArrayList<String> columns) {
        this.columns = columns; mode = SPECIFIC;
    }

    /**
     * Este método nos permite agregar un Nombre de Columna para el Comando a
     * ejecutar. Donde la columna se establece con un objeto
     * <code>String</code>.
     *
     * @param column Nombre de Columna del Comando
     */
    public void addColumn(String column) {
        columns.add(column);
    }

    /**
     * Este método nos permite establecer la Cantidad de Datos para insertar en
     * el Comando a ejecutar. Donde la cantidad de datos se establece con un
     * dato <code>int</code>. Ademas, determina que el modo de Insercción es
     * Estandar.
     *
     * @param numValues Cantidad de Datos a insertar en el Comando
     * @see #STANDARD
     */
    public void setValues(int numValues) {
        this.numValues = numValues; mode = STANDARD;
    }

    /**
     * Este método nos permite saber el modo de Insercción establecido en el
     * Comando a ejecutar. Donde el modo a retornar puede ser de 2 maneras, modo
     * Específico ó modo Estandar.
     *
     * @return Retorna la respuesta en un dato <code>boolean</code>.
     */
    public boolean getMode() {
        return mode;
    }

    // Metodos estáticos de la clase Insert
    /**
     * Este método nos permite crear un objeto Insert de modo Específico. Donde
     * la tabla se establece con un objeto <code>String</code> y las columnas
     * con un objeto <code>ArrayList</code>.
     *
     * @param table Nombre de Tabla del Comando
     * @param columns Nombre de Columnas del Comando
     * @return Retorna el insert en un objeto <code>Insert</code>.
     */
    public static Insert creatorCommand(String table, ArrayList<String> columns) {
        Insert insert = new Insert(); // Instanciando objeto
        insert.setTable(table); insert.setColumns(columns);

        return insert; // Retornando Objeto INSERT
    }

    /**
     * Este método nos permite crear un objeto Insert de modo Estandar. Donde la
     * tabla se establece con un objeto <code>String</code> y la cantidad de
     * datos con un dato <code>int</code>.
     *
     * @param table Nombre de Tabla del Comando
     * @param numValues Cantidad de Datos a insertar en el Comando
     * @return Retorna el insert en un objeto <code>Insert</code>.
     */
    public static Insert creatorCommand(String table, int numValues) {
        Insert insert = new Insert(); // Instanciando objeto
        insert.setTable(table); insert.setValues(numValues);

        return insert; // Retornando Objeto INSERT
    }

    // Metodos sobreescritos de la clase Insert
    @Override
    public String getCommand() throws DMLException {
        if ((table == null) || (table.isEmpty())) {
            throw new DMLException(DMLException.TABLE_UNDEFINED);
        } // No ha establecido el Nombre de Tabla

        // Declarando y configurando dato para Proceso
        String commandInsert = "INSERT INTO " + table;

        if (mode) {
            if ((columns == null) || (columns.isEmpty())) {
                throw new DMLException(DMLException.COLUMNS_UNDEFINED);
            } // No ha definido las Columnas de la Sentencia

            commandInsert += " (" + ConfiguratorCommand.columnsForCommand(columns) + ")";
            commandInsert += " VALUES (" + ConfiguratorCommand.valuesForSentence(columns.size()) + ")";
        } // Tipo de Insert Especifico
        else {
            if (numValues <= 0) {
                throw new DMLException(DMLException.VALUES_UNDEFINED);
            } // No ha definido el numero de Values correctos

            commandInsert += " VALUES (" + ConfiguratorCommand.valuesForSentence(numValues) + ")";
        } // Tipo de Insert Estandar

        return commandInsert; // Retornando comando INSERT
    }
}